package com.boil.qz.safekavass.shiro.realm;

import com.boil.qz.safekavass.model.LoginUser;
import com.boil.qz.safekavass.pojo.RoleResourceVo;
import com.boil.qz.safekavass.service.LoginUserService;
import com.boil.qz.safekavass.service.PermissionService;
import com.boil.util.BaseController;
import com.boil.util.Constants;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Created by ChenYong on 2017-05-03.
 * <br>
 * 用户授权认证。
 */
public class UserAuthRealm extends AuthorizingRealm {
    /**
     * 日志
     */
    private static Logger log = LoggerFactory.getLogger(BaseController.class);
    /**
     * 注入用户 Service
     */
    @Autowired
    private LoginUserService loginUserService;
    /**
     * 注入权限 Service
     */
    @Autowired
    private PermissionService permissionService;

    /**
     * 获取授权信息。
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        log.info("账号：{}--->进行授权", principalCollection.getPrimaryPrincipal());

        // 获取登录用户的操作信息
        Subject subject = SecurityUtils.getSubject();
        // 获取 Session
        Session session = subject.getSession();
        // 获取登录用户
        LoginUser loginUser = (LoginUser) session.getAttribute(Constants.LOGIN_USER);
        // 查询登录用户的角色资源关联
        List<RoleResourceVo> roleResourceVos = permissionService.findRoleResourceByUserId(loginUser.getId());
        // 登录用户拥有的角色
        Set<String> loginUserRoles = new HashSet<String>();
        // 登录用户拥有的权限
        Set<String> loginUserPerms = new HashSet<String>();

        // 整理角色和权限
        for (RoleResourceVo roleResourceVo : roleResourceVos) {
            loginUserRoles.add(roleResourceVo.getRoleCode());
            loginUserPerms.add(roleResourceVo.getPermissionCode());
        }

        // 简单授权信息
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        // 开始授权
        simpleAuthorizationInfo.addRoles(loginUserRoles);
        simpleAuthorizationInfo.addStringPermissions(loginUserPerms);

        log.info("账号：{}--->拥有角色：{}，拥有权限：{}", principalCollection.getPrimaryPrincipal(), simpleAuthorizationInfo.getRoles(), simpleAuthorizationInfo.getStringPermissions());

        return simpleAuthorizationInfo;
    }

    /**
     * 获取身份验证（登录验证）信息。
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        // 获取登录令牌
        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) authenticationToken;
        // 获取账号
        String account = usernamePasswordToken.getUsername();
        // 查询登录用户
        LoginUser loginUser = loginUserService.findByLoginid(account);

        log.info("账号：{}--->进行登录验证", account);

        // 简单身份验证信息
        SimpleAuthenticationInfo saInfo = null;

        // 登录账号找到
        if (loginUser != null) {
            saInfo = new SimpleAuthenticationInfo(account, loginUser.getPwd(), loginUser.getLoginName());
        }

        return saInfo;
    }

    /**
     * 清空授权缓存。
     */
    public void clearAuthorizationCache() {
        getAuthorizationCache().clear();
    }
}